﻿/*
 * This file is a part of the Smug# open source project.
 * 
 * Copyright (C) 2010, Troy Simpson 
 * 
 * Project Home: http://www.ebswift.com
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * 
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using FlickrNet;
using System.Windows.Media.Imaging;
using System.IO;
using System.Net;

namespace copy2smug
{
    public delegate void FlickrPhotoEventHandler(Photo photo);
    public delegate void FlickrBitmapLoadEventHandler(Photo photo);

    /// <summary>
    /// Used to populate the Flickr Photos Listbox.
    /// </summary>
    class FlickrPhotos
    {
        private static Flickr m_flickr; // flickr object gets sent from main UI
        private static Photoset m_photoset; // carries the selected photoset ID from the main UI
        private static Window1 m_w1; // reference to main UI
        public static List<FlickrPhoto> PhotoList = new List<FlickrPhoto>(); // contains the list we'll be sending back to the main UI

        public static event EventHandler Started; // started building the list
        public static event EventHandler Complete; // completed building the list
        public static event FlickrPhotoEventHandler NewPhoto; // used for each new photo iteration
        public static event FlickrBitmapLoadEventHandler NewBitmap; // used for bitmap loaded for each new photo
        private static AutoResetEvent bmiLoad = new AutoResetEvent(true);

        protected void OnStarted(EventArgs e)
        {
            EventHandler myEvent = Started;

            if (myEvent != null)
            {

                myEvent(this, e);
            }
        }

        protected void OnComplete(List<FlickrPhoto> photo)
        {
            EventHandler myEvent = Complete;

            if (myEvent != null)
            {
                myEvent(this, EventArgs.Empty);
            }
        }

        protected void OnNewPhoto(Photo photo)
        {
            FlickrPhotoEventHandler myEvent = NewPhoto;

            if (myEvent != null)
            {
                myEvent(photo);
            }
        }

        protected void OnNewBitmap(Photo photo)
        {
            FlickrBitmapLoadEventHandler myEvent = NewBitmap;

            if (myEvent != null)
            {
                myEvent(photo);
            }
        }

        /// <summary>
        /// Starts the thread to load the list of photos.
        /// </summary>
        /// <param name="flickr">Flickr object sent from the main UI carries current auth token etc.</param>
        /// <param name="photoset">Carries the selected flickr photoset from the main UI.</param>
        /// <param name="w1">Reference back to the main UI.</param>
        public static void LoadPhotos(Flickr flickr, Photoset photoset, Window1 w1)
        {
            m_flickr = flickr;
            m_photoset = photoset;
            m_w1 = w1;

            NewPhoto +=new FlickrPhotoEventHandler(FlickrPhotos_NewPhoto);

            Thread t = new Thread(doLoadPhotos);
            t.Start();
        }

        /// <summary>
        /// Handle the event for a new photo adding to the list.
        /// </summary>
        /// <param name="photo">Photo object retrieved from flickr</param>
        /// <remarks>Performs UI-centric operations (creating bitmap, updating the list) in the UI thread.</remarks>
        private static void FlickrPhotos_NewPhoto(Photo photo)
        {
            BitmapImage bmi;
            bmi = new BitmapImage();

            bmi.BeginInit();
            bmi.UriSource = new Uri(photo.ThumbnailUrl);
            bmi.EndInit();

            PhotoList.Insert(0, new FlickrPhoto(bmi, photo));
        }

        private static void bmi_DownloadCompleted(object sender, EventArgs e)
        {
            bmiLoad.Set();
        }

        /// <summary>
        /// Performs the long operation of iterating the selected set and building the bitmap images.
        /// </summary>
        public static void doLoadPhotos()
        {
            m_w1.Dispatch(w =>
            {
                Started(null, EventArgs.Empty);
            });

            PhotosetPhotoCollection pspc = new PhotosetPhotoCollection();

            pspc = m_flickr.PhotosetsGetPhotos(m_photoset.PhotosetId, PhotoSearchExtras.All);

            // return control to the UI thread to set the photo - errors occur if you try to create a bitmap in a worker thread
            foreach (Photo ph in pspc)
            {
                m_w1.Dispatch(w =>
                {
                    NewPhoto(ph);
                });
            }

            m_w1.Dispatch(w =>
            {
                Complete(null, null);
            });
        }
    }

    /// <summary>
    /// Used to provide an object to fill the FlickrPhoto list.
    /// </summary>
    public class FlickrPhoto
    {
        [System.Reflection.ObfuscationAttribute]
        public BitmapImage PhotoBitmap { get; set; }
        public Photo PhotoInfo { get; set; }

        public FlickrPhoto(BitmapImage bmi, Photo ph)
        {
            PhotoBitmap = bmi;
            PhotoInfo = ph;
        }
    }

    /// <summary>
    /// Used to populate the Flickr sets combobox.
    /// </summary>
    class FlickrSets
    {
        public static List<Photoset> LoadSets(Flickr flickr)
        {
            PhotosetCollection psc = flickr.PhotosetsGetList();
            List<Photoset> ilist = new List<Photoset>();

            foreach (Photoset ps in psc)
            {
                ilist.Add(ps);
            }

            return ilist;
        }
    }
}
